package com.wkbb.basic.controller.manage;

import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson.JSONArray;
import com.github.pagehelper.PageInfo;
import com.wkbb.basic.model.UserInfo;
import com.wkbb.basic.service.SysFunctionService;
import com.wkbb.basic.service.SysRoleService;
import com.wkbb.basic.service.UserService;
import com.wkbb.basic.vo.SysFunctionVo;
import com.wkbb.common.base.BaseController;
import com.wkbb.common.config.ServiceConfig;
import com.wkbb.common.constants.ErrorCode;
import com.wkbb.common.constants.RedisKeyConstant;
import com.wkbb.common.constants.VersionConstant;
import com.wkbb.common.dto.ResultDTO;
import com.wkbb.common.dto.basic.EmployeeInfoDto;
import com.wkbb.common.dto.basic.StudentInfoDto;
import com.wkbb.common.dto.basic.SysFunctionDto;
import com.wkbb.common.dto.basic.UserDto;
import com.wkbb.common.enums.SysRoleTypeEnum;
import com.wkbb.common.redis.RedisTemplateUtil;
import com.wkbb.common.redis.UserRedisTemplateUtil;
import com.wkbb.common.utils.BeanUtil;
import com.wkbb.common.utils.StringUtil;
import com.wkbb.common.utils.TokenUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * @author liuxiancan
 * 创建时间：2019年07月01日
 */
@RestController
@Api(description = "用户管理(后台管理)")
@RequestMapping("/basic/{apiVersion}/user/manage")
@Slf4j
public class UserManageController extends BaseController {

    @Autowired
    private ServiceConfig serviceConfig;

    @Autowired
    private UserService userService;

    @Autowired
    private SysRoleService sysRoleService;

    @Autowired
    private SysFunctionService sysFunctionService;

    @Autowired
    private UserRedisTemplateUtil redisTemplateUtil;

    @ApiOperation(value = "获取小程序用户列表")
    @RequestMapping(value = "/getAppletUserPageList", method = RequestMethod.GET)
    public ResultDTO<PageInfo<UserDto>> getAppletUserPageList(
            @ApiParam(value = "接口版本", defaultValue = VersionConstant.V1, required = true) @PathVariable(name = "apiVersion") String apiVersion,
            @ApiParam(value = "手机号码", required = false) @RequestParam(name = "mobile", required = false) String mobile,
            @ApiParam(value = "页码", required = false) @RequestParam(name = "pageNo", required = false, defaultValue = "1") Integer pageNo,
            @ApiParam(value = "每页条数", required = false) @RequestParam(name = "pageSize", required = false, defaultValue = "10") Integer pageSize) {
        UserDto userDto = getUserByLogin();
        if (userDto == null) {
            return new ResultDTO<>(ErrorCode.USER_NOT_EXIST);
        }
        try {
            HashMap<String, Object> params = new HashMap<>();
            if (!StringUtil.isNullOrBlank(mobile)) {
                params.put("mobile", mobile);
            }
            return new ResultDTO(userService.getAppletUserPageList(params, pageNo, pageSize));
        } catch (Exception e) {
            log.error("***********StudentManageController.getStudentInfoPageList******", e);
            return new ResultDTO<>(false);
        }
    }

    @ApiOperation(value = "检查手机号码是否可用")
    @RequestMapping(value = "/checkMobile", method = RequestMethod.GET)
    public ResultDTO<EmployeeInfoDto> checkMobile(
            @ApiParam(value = "接口版本", defaultValue = VersionConstant.V1, required = true) @PathVariable(name = "apiVersion") String apiVersion,
            @ApiParam(value = "手机号码", required = true) @RequestParam(name = "mobile", required = true) String mobile,
            @ApiParam(value = "卡号", required = true) @RequestParam(name = "cardNo", required = true) String cardNo,
            @ApiParam(value = "教工号/学号", required = true) @RequestParam(name = "jobNo", required = true) String jobNo,
            @ApiParam(value = "角色类型", required = true) @RequestParam(name = "roleType", required = true) Integer roleType,
            @ApiParam(value = "手机号码", required = true) @RequestParam(name = "orgId", required = true) Long orgId,
            @ApiParam(value = "用户ID", required = false) @RequestParam(name = "userId", required = false) Long userId) {
        log.info("***********UserController.checkMobile******apiVersion:{},mobile:{},cardNo:{},jobNo:{},roleType:{},orgId:{},userId:{}",
                apiVersion, mobile, cardNo, jobNo, roleType, orgId, userId);

        UserDto userDto = getUserByLogin();
        if (userDto == null) {
            return new ResultDTO<>(ErrorCode.USER_NOT_EXIST);
        }

        try {
            ErrorCode result = userService.checkMobileErrorCode(mobile, cardNo, jobNo, userId, roleType, orgId,null);
            if (result == null) {
                return new ResultDTO<>(true);
            } else {
                return new ResultDTO<>(result);
            }
        } catch (Exception e) {
            log.error("***********UserController.checkMobile******{}", e);
            return new ResultDTO<>(false);
        }
    }

    @ApiOperation(value = "后台用户登录")
    @RequestMapping(value = "/loginByPwd", method = RequestMethod.GET)
    public ResultDTO<List<UserDto>> loginByPwd(
            @ApiParam(value = "接口版本", defaultValue = VersionConstant.V1, required = true) @PathVariable(name = "apiVersion") String apiVersion,
            @ApiParam(value = "账号", required = false) @RequestParam(name = "account", required = false) String account,
            @ApiParam(value = "密码", required = false) @RequestParam(name = "password", required = false) String password) {

        log.info("**********UserController.loginByPwd********apiVersion:{},account:{},password:{}", apiVersion, account, password);
        if (StringUtils.isEmpty(account) || StringUtils.isEmpty(password)) {
            return new ResultDTO<>(ErrorCode.PARAM_MISSING);
        }

        try {

            List<UserDto> userList = userService.loginByPwd(account, password);
            if (userList == null || userList.isEmpty()){
                return ResultDTO.errorResult("账号或密码错误");
            }
            return new ResultDTO<>(userList);

        } catch (Exception e) {
            log.error("**********UserController.loginByPwd********", e);
            return new ResultDTO<>(false);
        }
    }

    @ApiOperation(value = "后台用户登录生成token")
    @RequestMapping(value = "/getLoginToken", method = RequestMethod.GET)
    public ResultDTO<String> getLoginToken(
            @ApiParam(value = "接口版本", defaultValue = VersionConstant.V1, required = true) @PathVariable(name = "apiVersion") String apiVersion,
            @ApiParam(value = "账户ID", required = false) @RequestParam(name = "accountId", required = false) Long accountId,
            @ApiParam(value = "组织ID", required = false) @RequestParam(name = "orgId", required = false) Long orgId,
            @ApiParam(value = "用户ID", required = false) @RequestParam(name = "userId", required = false) Long userId) {

        log.info("**********UserController.getLoginToken********apiVersion:{},orgId:{},userId:{}", apiVersion, accountId, orgId, userId);
//        if (null == accountId || orgId == null || userId == null) {
//            return new ResultDTO<>(ErrorCode.PARAM_MISSING);
//        }
        
        if (orgId == null || userId == null) {
            return new ResultDTO<>(ErrorCode.PARAM_MISSING);
        }

        try {

            UserDto userDto = userService.getUserInfoManage(accountId, orgId, userId,false);

            //组装TOKEN KEY
           // String key = accountId + "-" + orgId + "-" + userId;
            String key =  orgId + "-" + userId;

            //生成token值
            TokenUtil tokenUtil = new TokenUtil(serviceConfig.getTokenSecretKey(), serviceConfig.getTokenAlgorithm());
            String token = tokenUtil.getToken(key);

            String redisKey = RedisKeyConstant.WKBB_BASIC_USER_BACK + RedisKeyConstant.WKBB_BASIC_USER_BACK_TOKEN + token;

            redisTemplateUtil.set(redisKey, userDto, RedisKeyConstant.EXPIRATION_TIME_1_WEEK);

            log.info("**********UserController.getLoginToken********key:{},token:{}", key, token);

            return new ResultDTO<String>(token);

        } catch (Exception e) {
            log.error("**********UserController.getLoginToken********", e);
            return new ResultDTO<>(false);
        }
    }

    @ApiOperation(value = "后台用户登出")
    @RequestMapping(value = "/loginOut", method = RequestMethod.GET)
    public ResultDTO<Object> loginOut(@ApiParam(value = "接口版本", defaultValue = VersionConstant.V1, required = true) @PathVariable(name = "apiVersion") String apiVersion) {

        log.info("**********UserController.loginOut********apiVersion:{}", apiVersion);
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

        String token = request.getHeader("token");

        if (StringUtil.isEmpty(token)) {
            return null;
        }

        try {

            String redisKey = RedisKeyConstant.WKBB_BASIC_USER_BACK + RedisKeyConstant.WKBB_BASIC_USER_BACK_TOKEN + token;

            redisTemplateUtil.delete(redisKey);

            return new ResultDTO(true);

        } catch (Exception e) {
            log.error("**********UserController.loginByPwd********", e);
            return new ResultDTO<>(false);
        }
    }

    @ApiOperation(value = "后台用户查询菜单")
    @RequestMapping(value = "/getUserMenuTreeList", method = RequestMethod.GET)
    public ResultDTO<List<SysFunctionVo>> getUserMenuTreeList(
            @ApiParam(value = "接口版本", defaultValue = VersionConstant.V1, required = true) @PathVariable(name = "apiVersion") String apiVersion) {
        log.info("**********getUserMenuTreeList********apiVersion:{}", apiVersion);
        UserDto userDto = getUserByLogin();
        if (userDto == null) {
            return new ResultDTO<>(ErrorCode.USER_NOT_EXIST);
        }

        HashMap<String, Object> params = new HashMap<String, Object>();
        params.put("status",1);
        try {
//            Long orgId = super.getOrgByUser(userDto).getId();
            Integer roleType = getRoleTypeByUser(userDto);
            if (SysRoleTypeEnum.SUPER_ADMIN.getValue() == roleType) {
                return new ResultDTO<List<SysFunctionVo>>(sysFunctionService.getFunctionTreeList(params));
            }
            else
            {
                //根据当前用户查询菜单
//                params.put("orgId", orgId);
                params.put("userId", userDto.getId());
                params.put("parentId", 0);
                return new ResultDTO<List<SysFunctionVo>>(sysRoleService.getUserFunctionTreeList(params));
            }

        } catch (Exception e) {
            log.error("**********getUserMenuTreeList********", e);
            return new ResultDTO<>(false);
        }
    }

    @ApiOperation(value = "后台查询用户按钮权限")
    @RequestMapping(value = "/getUserMenuButtonList", method = RequestMethod.GET)
    public ResultDTO<List<SysFunctionVo>> getUserMenuButtonList(
            @ApiParam(value = "接口版本", defaultValue = VersionConstant.V1, required = true) @PathVariable(name = "apiVersion") String apiVersion,
            @ApiParam(value = "菜单ID", required = true) @RequestParam(name = "functionId", required = true) Long functionId) {
        log.info("**********getUserMenuButtonList********apiVersion:{},functionId:{}", apiVersion, functionId);
        UserDto userDto = getUserByLogin();
        if (userDto == null) {
            return new ResultDTO<>(ErrorCode.USER_NOT_EXIST);
        }

        try {
            Long orgId = ((JSONArray) userDto.getRoleType()).getJSONObject(0).getLong("orgId");

            HashMap<String, Object> params = new HashMap<String, Object>();
            params.put("orgId", orgId);
            params.put("userId", userDto.getId());
            params.put("functionId", functionId);

            return new ResultDTO<List<SysFunctionVo>>(sysRoleService.getUserMenuButtonList(params));

        } catch (Exception e) {
            log.error("**********getUserMenuButtonList********", e);
            return new ResultDTO<>(false);
        }
    }

    @ApiOperation(value = "后台用户查询菜单(对外)")
    @RequestMapping(value = "/getOpenMenuTreeList", method = RequestMethod.GET)
    public ResultDTO<List<SysFunctionDto>> getOpenMenuTreeList(
            @ApiParam(value = "接口版本", defaultValue = VersionConstant.V1, required = true) @PathVariable(name = "apiVersion") String apiVersion,
            @ApiParam(value = "token", required = true) @RequestParam(name = "token", required = true) String token,
            @ApiParam(value = "模块", required = false) @RequestParam(name = "model", required = false) String model) {

        log.info("**********getOpenMenuTreeList********token:{}", token);
        UserDto userDto = getUserByLogin(token);
        if (userDto == null) {
            return new ResultDTO<>(ErrorCode.USER_NOT_EXIST);
        }

        try {

            List<SysFunctionVo> sysFunctionVoList = null;
            Long orgId = super.getOrgByUser(userDto).getId();
            Integer roleType = getRoleTypeByUser(userDto);
            HashMap<String, Object> params = new HashMap<String, Object>();
            if (SysRoleTypeEnum.SUPER_ADMIN.getValue() == roleType) {
                params.put("parentId", 0);
                sysFunctionVoList = sysFunctionService.getFunctionTreeList(new HashMap<String, Object>());
            }
            else {
                //根据当前用户查询菜单
                params.put("orgId", orgId);
                params.put("userId", userDto.getId());
                params.put("parentId", 0);

                sysFunctionVoList = sysRoleService.getUserFunctionTreeList(params);
            }

            if (!sysFunctionVoList.isEmpty()) {
                List<SysFunctionDto> sysFunctionDtoList = BeanUtil.copyPropertiesList(sysFunctionVoList, SysFunctionDto.class);
                return new ResultDTO<List<SysFunctionDto>>(sysFunctionDtoList);
            }

            return new ResultDTO<>(true);
        } catch (Exception e) {
            log.error("**********getOpenMenuTreeList********", e);
            return new ResultDTO<>(false);
        }
    }
}
